package com.wechat.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wechat.admin.common.CommonConstants;
import com.wechat.admin.exception.BusinessException;
import com.wechat.admin.exception.ErrorCode;
import com.wechat.admin.mapper.*;
import com.wechat.admin.model.dto.*;
import com.wechat.admin.model.entity.*;
import com.wechat.admin.model.request.*;
import com.wechat.admin.model.vo.*;
import com.wechat.admin.response.PageResponse;
import com.wechat.admin.service.AssembleService;
import com.wechat.admin.service.ConverterService;
import com.wechat.admin.service.WeDeviceService;
import com.wechat.admin.utils.RestTemplateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @Author:sjb
 * @CreateTime:2024-12-15
 * @Description: 设备服务实现类
 * @Version：1.0
 */
@Slf4j
@Component
public class WeDeviceServiceImpl extends ServiceImpl<WeDeviceMapper, WeDevice>
        implements WeDeviceService {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Value("${gewe.getQrCode.path}")
    private String getQrCodePath;

    @Value("${gewe.weChatToken.path}")
    private String getWeChatTokenPath;

    @Value("${gewe.weChatLogin.path}")
    private String weChatLoginPath;

    @Value("${gewe.weChatOnline.path}")
    private String weChatOnlinePath;

    @Value("${gewe.weChatLogOut.path}")
    private String weChatLogOutPath;

    @Resource
    private WeDeviceMapper weDeviceMapper;

    @Resource
    private UserDeviceLinkMapper userDeviceLinkMapper;

    @Resource
    private QrcodeRequestLogMapper qrcodeRequestLogMapper;

    @Resource
    private WechatLoginRequestLogMapper wechatLoginRequestLogMapper;

    @Resource
    private GeweDockerTokenWithPortMapper geweDockerTokenWithPortMapper;

    @Resource
    private AssembleService assembleService;

    @Resource
    private ConverterService converterService;
    @Autowired
    private UserServiceImpl userServiceImpl;

    @Resource
    private TokenGroupLinkMapper tokenGroupLinkMapper;


    @Override
    public Map<Long, List<WeDeviceDto>> getDeviceListByUserIds(List<Long> userIdList) {
        if (CollectionUtils.isEmpty(userIdList)) {
            return Collections.emptyMap();
        }
        List<WeDeviceDto> devicesByUserIds = weDeviceMapper.findDevicesByUserIds(userIdList);
        // 按 userId 分组
        return devicesByUserIds.stream()
                .collect(Collectors.groupingBy(WeDeviceDto::getUserid));
    }

    /**
     * 获取登录二维码 请求头传token
     *
     * @param getLoginQrCodeRequest
     * @return
     */
    @Override
    public LoginQrCodeVo getLoginQrCode(GetLoginQrCodeRequest getLoginQrCodeRequest) {
        // 登录后台某个容器时 申请到的token 一个容器只允许登录2个设备
        Integer code = null;
        String msg = null;
        String data = null;

        // 请求日志表字段
        String requestBody;
        String responseBody = null;
        String exceptionMsg = null;
        Long userId = getLoginQrCodeRequest.getUserId();
        boolean firstLogin = getLoginQrCodeRequest.isFirstLogin();
        String deviceId = getLoginQrCodeRequest.getDeviceId();
        String token = getLoginQrCodeRequest.getToken();
        if (firstLogin) {
            HttpHeaders header = RestTemplateUtil.Header.builder()
                    .add("X-GEWE-TOKEN", token)
                    .build();

            // 如果是第一次登录 不需要传deviceId 头要传token
            Map<String, Object> body = RestTemplateUtil.PostBody.builder()
                    .add("appId", "")
                    .build();

            requestBody = body.toString();

            try {
                JSONObject jsonObject = RestTemplateUtil.postForTest(getQrCodePath, header, body);
                code = jsonObject.getInteger("ret");
                msg = jsonObject.getString("msg");
                data = jsonObject.getString("data");

                responseBody = jsonObject.toJSONString();

                if (CommonConstants.SUCCESS.equals(code) && CommonConstants.SUCCESS_MSG.equals(msg)) {
                    if (!StrUtil.isEmpty(data)) {
                        LoginQrCodeDto loginQrCodeDto = OBJECT_MAPPER.readValue(data,
                                new TypeReference<LoginQrCodeDto>() {
                                });
                        if (loginQrCodeDto != null) {
                            return assembleService.dtoToQrCodeVo(token, loginQrCodeDto);
                        }
                    }
                } else if (CommonConstants.FAILED.equals(code)) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, msg);
                }
            } catch (Exception e) {
                exceptionMsg = e.getMessage();
                log.info("请求生成二维码接口异常,data:{},code:{},msg:{}", data, code, msg);
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "生成二维码异常");
            } finally {
                saveQrCodeLog(userId, deviceId, requestBody, responseBody, exceptionMsg);
            }
        } else {
            // todo 不是第一次登录可能是 组下的其他用户共享token  再次登录自己的微信在这个设备上 这种情况特殊处理
            HttpHeaders header = RestTemplateUtil.Header.builder()
                    .add("X-GEWE-TOKEN", token)
                    .build();
            Map<String, Object> body = RestTemplateUtil.PostBody.builder()
                    .add("appId", deviceId)
                    .build();
            requestBody = body.toString();

            try {
                JSONObject jsonObject = RestTemplateUtil.postForTest(getQrCodePath, header, body);
                code = jsonObject.getInteger("ret");
                msg = jsonObject.getString("msg");
                data = jsonObject.getString("data");
                responseBody = jsonObject.toJSONString();
                if (CommonConstants.SUCCESS.equals(code) && CommonConstants.SUCCESS_MSG.equals(msg)) {
                    LoginQrCodeDto loginQrCodeDto = OBJECT_MAPPER.readValue(data,
                            new TypeReference<LoginQrCodeDto>() {
                            });
                    if (loginQrCodeDto != null) {
                        return assembleService.dtoToQrCodeVo(token, loginQrCodeDto);
                    }
                } else if (CommonConstants.FAILED.equals(code)) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, msg);
                }
            } catch (Exception e) {
                exceptionMsg = e.getMessage();
                log.info("请求生成二维码接口异常,data:{},code:{},msg:{}", data, code, msg);
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "生成二维码异常");
            } finally {
                saveQrCodeLog(userId, deviceId, requestBody, responseBody, exceptionMsg);
            }
        }
        return null;
    }

    /**
     * 扫码之后的请求登录
     *
     * @param weChatLoginRequest
     * @return
     */
    @Override
    @Async
    public WeChatLoginInfoVo weChatLogin(WeChatLoginRequest weChatLoginRequest) {
        String appId = weChatLoginRequest.getAppId();
        String uuid = weChatLoginRequest.getUuid();
        String token = weChatLoginRequest.getToken();
        Long userId = weChatLoginRequest.getUserId();
        String deviceName = weChatLoginRequest.getDeviceName();
        String description = weChatLoginRequest.getDescription();

        HttpHeaders header = RestTemplateUtil.Header.builder()
                .add("X-GEWE-TOKEN", token)
                .build();

        Map<String, Object> body = RestTemplateUtil.PostBody.builder()
                .add("appId", appId)
                .add("uuid", uuid)
                .build();

        JSONObject jsonObject = null;
        Long logId = null;
        try {
            Thread.sleep(3000);
            jsonObject = RestTemplateUtil.postForTest(weChatLoginPath, header, body);
            logId = insertRequestLog(header, body);
        } catch (InterruptedException e) {
            // 恢复中断状态
            Thread.currentThread().interrupt();
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "请求微信登录接口失败");
        }

        if (jsonObject == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求微信登录接口返回为空");
        }

        Integer code = jsonObject.getInteger("ret");
        String msg = jsonObject.getString("msg");
        JSONObject data = jsonObject.getJSONObject("data");

        updateRequestLog(logId, jsonObject.toString(), null);

        if (CommonConstants.SUCCESS.equals(code) && CommonConstants.SUCCESS_MSG.equals(msg)) {
            JSONObject loginInfo = data.getJSONObject("loginInfo");

            if (loginInfo == null) {
                return createWeChatLoginInProgressVo();
            }
            log.info("loginInfo的信息为：{}", loginInfo);
            WeChatLoginInfoDto weChatLoginInfoDto = null;
            try {
                weChatLoginInfoDto = OBJECT_MAPPER.readValue(loginInfo.toString(),
                        new TypeReference<WeChatLoginInfoDto>() {
                        });
            } catch (IOException e) {
                log.error("JSON 转换为 WeChatLoginInfoDto 失败，输入内容: {}", loginInfo, e);
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "JSON解析异常");
            }

            if (weChatLoginInfoDto != null) {
                // 此设备可能不是第一次登录了 先查询设备表有没有这条记录
                QueryWrapper<UserDeviceLink> userDeviceLinkQueryWrapper = new QueryWrapper<>();
                userDeviceLinkQueryWrapper.eq("userid", userId);
                userDeviceLinkQueryWrapper.eq("deviceid", appId);
                UserDeviceLink userDeviceLink = userDeviceLinkMapper.selectOne(userDeviceLinkQueryWrapper);
                if (userDeviceLink != null) {
                    Long deviceIdLink = userDeviceLink.getDeviceIdLink();
                    updateDeviceLoginTime(deviceIdLink);
                } else {
                    // 保存返回的信息到设备表
                    WeDevice weDevice = saveToDevice(deviceName, appId, uuid, token, weChatLoginInfoDto);
                    // 保存信息到用户设备关联表
                    Long id = weDevice.getId();
                    saveToUserDeviceLink(description, id, appId, userId);
                    updateDockerTokenStatus(token, deviceName);
                }
                return assembleService.dtoToWeChatLoginInfoVo(appId, weChatLoginInfoDto);
            }
        } else if (CommonConstants.FAILED.equals(code) && StringUtils.equalsIgnoreCase(msg, CommonConstants.PROCESSING_MSG)) {
            return createWeChatLoginInProgressVo();
        } else if (CommonConstants.FAILED.equals(code)) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, msg);
        }
        return null;
    }

    @Override
    public Map<String, Boolean> checkOnline(CheckOnlineRequest checkOnlineRequest) {
        List<DeviceStatusRequest> deviceRequestList = checkOnlineRequest.getDeviceRequestList();
        // 使用线程池并发查询
        ExecutorService executor = Executors.newFixedThreadPool(10);
        // 所有的异步任务 每个CompletableFuture代表一个异步任务
        List<CompletableFuture<Pair<String, Boolean>>> futures = deviceRequestList.stream()
                .map(device -> CompletableFuture.supplyAsync(() -> {
                    String appId = device.getDeviceId();
                    String token = device.getToken();
                    // key是appId，value是状态
                    return Pair.of(appId, queryDeviceOnlineStatus(appId, token));
                }, executor))
                .collect(Collectors.toList());
        Map<String, Boolean> onlineStatusMap = futures.stream().distinct()
                .map(CompletableFuture::join)
                .collect(Collectors.toMap(Pair::getKey, Pair::getValue));

        executor.shutdown();
        return onlineStatusMap;
    }

    /**
     * 修改token使用状态 为正在使用中 2
     *
     * @param token
     * @param deviceName
     */
    private void updateDockerTokenStatus(String token, String deviceName) {
        QueryWrapper<GeweDockerTokenWithPort> geweDockerTokenQueryWrapper = new QueryWrapper<>();
        geweDockerTokenQueryWrapper.eq("gewe_token", token);
        geweDockerTokenQueryWrapper.eq("device_name", deviceName);
        GeweDockerTokenWithPort geweDockerTokenWithPort = geweDockerTokenWithPortMapper.selectOne(geweDockerTokenQueryWrapper);
        if (geweDockerTokenWithPort != null) {
            // token正在被使用中
            geweDockerTokenWithPort.setIsused(CommonConstants.TOKEN_STATUS.USED);
            geweDockerTokenWithPortMapper.update(geweDockerTokenWithPort, geweDockerTokenQueryWrapper);
        } else {
            log.info("未查询到使用Token信息");
        }
    }

    @Override
    public List<DockerTokenVo> getUsableToken() {
        List<DockerTokenDto> allUsableToken = geweDockerTokenWithPortMapper.getAllUsableToken();
        if (CollectionUtils.isEmpty(allUsableToken)) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "暂无可使用设备,请联系人员添加");
        }
        return converterService.dockerTokenDtoToVo(allUsableToken);
    }

    @Override
    public List<UsableDeviceVo> getUsableDeviceList() {
        UserLoginInfoVo currentLoginUser = userServiceImpl.getCurrentLoginUser();
        Integer userGroup = currentLoginUser.getUserGroup();
        String username = currentLoginUser.getUsername();
        // 初始当前用户没有分组信息 看不到组下的用户信息
        String userRole = currentLoginUser.getUserRole();
        if (userGroup == null && CommonConstants.USER.equals(userRole)) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "请联系管理员为您分组并分配设备");
        }
        if (userGroup == null) {
            return Collections.emptyList();
        }
        List<WeDeviceDto> usableDevice = weDeviceMapper.findUsableDevice(userGroup, username);
        if (CollectionUtils.isEmpty(usableDevice)) {
            return Collections.emptyList();
        }
        return converterService.usableDeviceObjToVo(usableDevice);
    }

    /**
     * 微信退出接口
     *
     * @param weChatLogOutRequest
     * @return
     */
    @Override
    public Boolean weChatLogout(WeChatLogOutRequest weChatLogOutRequest) {
        String appId = weChatLogOutRequest.getAppId();
        String token = weChatLogOutRequest.getToken();

        HttpHeaders header = RestTemplateUtil.Header.builder()
                .add("X-GEWE-TOKEN", token)
                .build();

        Map<String, Object> body = RestTemplateUtil.PostBody.builder()
                .add("appId", appId)
                .build();
        JSONObject jsonObject = null;
        try {
            jsonObject = RestTemplateUtil.postForTest(weChatLogOutPath, header, body);
            log.info("请求退出登录的结果为：{}", jsonObject);
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "请求退出登录失败");
        }
        Integer code = jsonObject.getInteger("ret");
        String msg = jsonObject.getString("msg");

        if (CommonConstants.SUCCESS.equals(code) && CommonConstants.SUCCESS_MSG.equals(msg)) {
            return true;
        }
        return false;
    }

    @Override
    public AssignmentDeviceVo getAssignmentDeviceList(int currentPage, int pageSize) {
        int offset = (currentPage - 1) * pageSize;
        long total = tokenGroupLinkMapper.countAssignmentDevice();
        List<AssignmentDeviceDto> assignmentDevicePage = tokenGroupLinkMapper.getAssignmentDevicePage(pageSize, offset);
        List<AssignmentDeviceVo.Device> devices = converterService.assignmentDeviceDtoToVo(assignmentDevicePage);

        // 创建分页返回对象
        AssignmentDeviceVo pageResponse = new AssignmentDeviceVo();
        pageResponse.setTotal(total);
        pageResponse.setCurrentPage(currentPage);
        pageResponse.setPageSize(pageSize);
        pageResponse.setDeviceList(devices);

        return pageResponse;
    }

    @Override
    public Boolean delUserAndDevRelation(DelDeviceAndUserRelRequest delDeviceAndUserRelRequest) {
        String deviceId = delDeviceAndUserRelRequest.getDeviceId();
        String token = delDeviceAndUserRelRequest.getToken();
        Boolean logout = weChatLogout(new WeChatLogOutRequest(deviceId, token));

        if (!logout) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "请求退出接口失败");
        }
        unbindStatusAndReleaseToken(delDeviceAndUserRelRequest);
        return true;
    }


    /**
     * 解绑用户与设备状态并释放token
     *
     * @param delDeviceAndUserRelRequest
     */
    private void unbindStatusAndReleaseToken(DelDeviceAndUserRelRequest delDeviceAndUserRelRequest) {
        try {
            String token = delDeviceAndUserRelRequest.getToken();
            String deviceName = delDeviceAndUserRelRequest.getDeviceName();
            QueryWrapper<WeDevice> weDeviceQueryWrapper = new QueryWrapper<>();
            weDeviceQueryWrapper.eq("deviceid", delDeviceAndUserRelRequest.getDeviceId());
            weDeviceQueryWrapper.eq("token", token);
            WeDevice weDevice = weDeviceMapper.selectOne(weDeviceQueryWrapper);
            Long id = weDevice.getId();

            QueryWrapper<UserDeviceLink> deviceLinkQueryWrapper = new QueryWrapper<>();
            deviceLinkQueryWrapper.eq("deviceidlink", id);
            UserDeviceLink userDeviceLink = userDeviceLinkMapper.selectOne(deviceLinkQueryWrapper);
            if (weDevice != null && userDeviceLink != null) {
                weDevice.setStatus(CommonConstants.USE_DEVICE_REL_STATUS.UNBINDING_BY_USER);
                weDeviceMapper.updateById(weDevice);
            }
            // 释放token表中token的状态
            QueryWrapper<GeweDockerTokenWithPort> geweDockerTokenQueryWrapper = new QueryWrapper<>();
            geweDockerTokenQueryWrapper.eq("gewe_token", token);
            geweDockerTokenQueryWrapper.eq("device_name", deviceName);
            GeweDockerTokenWithPort geweDockerTokenWithPort = geweDockerTokenWithPortMapper.selectOne(geweDockerTokenQueryWrapper);
            if (geweDockerTokenWithPort != null) {
                geweDockerTokenWithPort.setIsused(CommonConstants.TOKEN_STATUS.UNASSIGNED);
                geweDockerTokenWithPortMapper.update(geweDockerTokenWithPort, geweDockerTokenQueryWrapper);
            } else {
                log.info("未查询到使用Token信息");
            }
        } catch (Exception e) {
            log.info("异常信息：{}", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新数据异常");
        }

    }


    /**
     * 查询设备是否在线状态
     *
     * @param appId
     * @param token
     * @return
     */
    public boolean queryDeviceOnlineStatus(String appId, String token) {

        HttpHeaders header = RestTemplateUtil.Header.builder()
                .add("X-GEWE-TOKEN", token)
                .build();

        Map<String, Object> body = RestTemplateUtil.PostBody.builder()
                .add("appId", appId)
                .build();
        JSONObject jsonObject = RestTemplateUtil.postForTest(weChatOnlinePath, header, body);
        Integer code = jsonObject.getInteger("ret");
        String msg = jsonObject.getString("msg");
        Boolean data = jsonObject.getObject("data", Boolean.class);

        if (CommonConstants.SUCCESS.equals(code) && CommonConstants.SUCCESS_MSG.equals(msg)) {
            return (boolean) data;
        }
        return false;
    }

    /**
     * 从GeWeDockerTokenWithPort表查token
     *
     * @return
     */
    private String getTokenFromGeWeDockerTokenWithPort(Long userId) {
        QueryWrapper<GeweDockerTokenWithPort> geweDockerTokenWithPortQueryWrapper = new QueryWrapper<>();
        // 代表目前可使用的
        geweDockerTokenWithPortQueryWrapper.eq("isused", 0);
        List<GeweDockerTokenWithPort> geWeDockerTokenWithPorts = geweDockerTokenWithPortMapper
                .selectList(geweDockerTokenWithPortQueryWrapper);
        if (geWeDockerTokenWithPorts.isEmpty()) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "当前已无可使用Token,请联系人员申请");
        }
        GeweDockerTokenWithPort geweDockerTokenWithPort = geWeDockerTokenWithPorts.get(0);
        String geWeToken = geweDockerTokenWithPort.getGewe_token();
        log.info("申请到的token为：{}", geWeToken);
        return geWeToken;
    }


    private Long insertRequestLog(HttpHeaders headers, Map<String, Object> body) {
        WechatLoginRequestLog wechatLoginRequestLog = new WechatLoginRequestLog();
        wechatLoginRequestLog.setRequestHeaders(headers.toString());
        wechatLoginRequestLog.setRequestBody(JSONObject.toJSONString(body));
        wechatLoginRequestLogMapper.insert(wechatLoginRequestLog);
        return wechatLoginRequestLog.getId();
    }

    private void updateRequestLog(Long logId, String responseMessage, String exceptionMessage) {
        WechatLoginRequestLog wechatLoginRequestLog = new WechatLoginRequestLog();
        wechatLoginRequestLog.setId(logId);
        wechatLoginRequestLog.setResponseMessage(responseMessage);
        wechatLoginRequestLog.setExceptionMessage(exceptionMessage);
        wechatLoginRequestLogMapper.updateById(wechatLoginRequestLog);
    }

    private WeChatLoginInfoVo createWeChatLoginInProgressVo() {
        WeChatLoginInfoVo vo = new WeChatLoginInfoVo();
        vo.setWeChatLoginStatus("登录中");
        return vo;
    }

    private void updateDeviceLoginTime(Long deviceIdLink) {
        WeDevice weDevice = weDeviceMapper.selectById(deviceIdLink);
        if (weDevice != null) {
            Date now = new Date();
            weDevice.setLoginTime(now);
            weDevice.setUpdateTime(now);
            weDeviceMapper.updateById(weDevice);
        }
    }


    public void saveQrCodeLog(Long userId, String deviceId, String requestBody, String responseBody, String exceptionMsg) {
        QrcodeRequestLog requestLog = new QrcodeRequestLog();
        requestLog.setUserid(userId);
        requestLog.setDeviceId(deviceId);
        requestLog.setRequestBody(requestBody);
        requestLog.setResponseBody(responseBody);
        requestLog.setExceptionMessage(exceptionMsg);
        requestLog.setCreateTime(new Date());
        qrcodeRequestLogMapper.insert(requestLog);
    }

    /**
     * 系统内部请求登录获取容器的Token
     *
     * @return
     */
    private String getLoginWechatToken() {
        // body 为空 请求头为空
        Map<String, Object> body = RestTemplateUtil.PostBody.builder().build();
        String code = null;
        String msg = null;
        String data = null;
        try {
            JSONObject jsonObject = RestTemplateUtil.post(getWeChatTokenPath, body);
            code = jsonObject.getString("ret");
            msg = jsonObject.getString("msg");
            data = jsonObject.getString("data");
        } catch (Exception e) {
            log.info("请求获取token接口异常：code:{},msg:{},data:{}", code, msg, data);
        }
        return data;
    }

    /**
     * 判断此用户的设备是不是第一次登录
     *
     * @param userId
     * @param
     * @return
     */
    private boolean isFirstLogin(Long userId, String deviceId) {
        // 如果用户设备关联表查不到用户关联的设备 说明是第一次登录
        QueryWrapper<UserDeviceLink> deviceLinkQueryWrapper = new QueryWrapper<>();
        deviceLinkQueryWrapper.eq("userid", userId);
        deviceLinkQueryWrapper.eq("deviceid", deviceId);
        List<UserDeviceLink> userDeviceLinks = userDeviceLinkMapper.selectList(deviceLinkQueryWrapper);
        if (CollectionUtils.isEmpty(userDeviceLinks)) {
            return true;
        }
        return false;
    }

    /**
     * 登录成功后 保存信息到设备表
     *
     * @param token
     * @param weChatLoginInfoDto
     */
    private WeDevice saveToDevice(String deviceName, String appId, String uuId,
                                  String token, WeChatLoginInfoDto weChatLoginInfoDto) {
        WeDevice weDevice = new WeDevice();
        // 登录成功 表示这个容器的token的一个槽位被占用 处于使用状态
        weDevice.setStatus(1);
        weDevice.setToken(token);
        weDevice.setWxId(weChatLoginInfoDto.getWxid());
        weDevice.setDeviceId(appId);
        weDevice.setLoginTime(new Date());
        weDevice.setUuid(uuId);
        weDevice.setDeviceName(deviceName);
        weDeviceMapper.insert(weDevice);
        return weDevice;
    }

    /**
     * 登录成功后保存信息到用户设备关联表
     */
    private void saveToUserDeviceLink(String description, Long id, String appId, Long userId) {
        UserDeviceLink userDeviceLink = new UserDeviceLink();
        userDeviceLink.setUserid(userId);
        userDeviceLink.setDeviceId(appId);
        userDeviceLink.setStatus(CommonConstants.USE_DEVICE_REL_STATUS.USED_BY_USER);
        userDeviceLink.setAssignedAt(new Date());
        userDeviceLink.setDeviceIdLink(id);
        userDeviceLink.setDescription(description);
        userDeviceLinkMapper.insert(userDeviceLink);
    }
}
